import dayjs from 'dayjs'

/**
 * 格式化日期时间
 */
export const formatDateTime = (date: string | Date, format = 'YYYY-MM-DD HH:mm:ss'): string => {
  return dayjs(date).format(format)
}

/**
 * 格式化相对时间
 */
export const formatRelativeTime = (date: string | Date): string => {
  return dayjs(date).fromNow()
}

/**
 * 格式化文件大小
 */
export const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

/**
 * 格式化执行时间
 */
export const formatDuration = (milliseconds: number): string => {
  if (milliseconds < 1000) {
    return `${milliseconds}ms`
  }
  
  const seconds = Math.floor(milliseconds / 1000)
  const minutes = Math.floor(seconds / 60)
  const hours = Math.floor(minutes / 60)
  
  if (hours > 0) {
    return `${hours}h ${minutes % 60}m ${seconds % 60}s`
  } else if (minutes > 0) {
    return `${minutes}m ${seconds % 60}s`
  } else {
    return `${seconds}s`
  }
}

/**
 * 防抖函数
 */
export const debounce = <T extends (...args: any[]) => any>(
  func: T,
  wait: number
): ((...args: Parameters<T>) => void) => {
  let timeout: NodeJS.Timeout | null = null
  
  return (...args: Parameters<T>) => {
    if (timeout) {
      clearTimeout(timeout)
    }
    
    timeout = setTimeout(() => {
      func(...args)
    }, wait)
  }
}

/**
 * 节流函数
 */
export const throttle = <T extends (...args: any[]) => any>(
  func: T,
  wait: number
): ((...args: Parameters<T>) => void) => {
  let lastTime = 0
  
  return (...args: Parameters<T>) => {
    const now = Date.now()
    
    if (now - lastTime >= wait) {
      lastTime = now
      func(...args)
    }
  }
}

/**
 * 深拷贝
 */
export const deepClone = <T>(obj: T): T => {
  if (obj === null || typeof obj !== 'object') {
    return obj
  }
  
  if (obj instanceof Date) {
    return new Date(obj.getTime()) as T
  }
  
  if (obj instanceof Array) {
    return obj.map(item => deepClone(item)) as T
  }
  
  if (typeof obj === 'object') {
    const cloned = {} as T
    Object.keys(obj).forEach(key => {
      cloned[key as keyof T] = deepClone(obj[key as keyof T])
    })
    return cloned
  }
  
  return obj
}

/**
 * 生成唯一ID
 */
export const generateId = (): string => {
  return Math.random().toString(36).substr(2, 9)
}

/**
 * 下载文件
 */
export const downloadFile = (blob: Blob, filename: string): void => {
  const url = window.URL.createObjectURL(blob)
  const link = document.createElement('a')
  link.href = url
  link.download = filename
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
  window.URL.revokeObjectURL(url)
}

/**
 * 复制到剪贴板
 */
export const copyToClipboard = async (text: string): Promise<boolean> => {
  try {
    if (navigator.clipboard && window.isSecureContext) {
      await navigator.clipboard.writeText(text)
      return true
    } else {
      // 降级方案
      const textArea = document.createElement('textarea')
      textArea.value = text
      textArea.style.position = 'fixed'
      textArea.style.left = '-999999px'
      textArea.style.top = '-999999px'
      document.body.appendChild(textArea)
      textArea.focus()
      textArea.select()
      const result = document.execCommand('copy')
      document.body.removeChild(textArea)
      return result
    }
  } catch (error) {
    console.error('复制到剪贴板失败:', error)
    return false
  }
}

/**
 * 验证SQL语法（简单版本）
 */
export const validateSQL = (sql: string): { valid: boolean; errors: string[] } => {
  const errors: string[] = []
  const trimmedSQL = sql.trim()
  
  if (!trimmedSQL) {
    errors.push('SQL语句不能为空')
    return { valid: false, errors }
  }
  
  // 检查是否包含危险操作
  const dangerousKeywords = ['DROP', 'DELETE', 'TRUNCATE', 'ALTER']
  const upperSQL = trimmedSQL.toUpperCase()
  
  dangerousKeywords.forEach(keyword => {
    if (upperSQL.includes(keyword)) {
      errors.push(`检测到潜在危险操作: ${keyword}`)
    }
  })
  
  // 检查基本语法
  const openParens = (trimmedSQL.match(/\(/g) || []).length
  const closeParens = (trimmedSQL.match(/\)/g) || []).length
  
  if (openParens !== closeParens) {
    errors.push('括号不匹配')
  }
  
  return {
    valid: errors.length === 0,
    errors
  }
}

/**
 * 格式化SQL（增强版本）
 */
export const formatSQL = (sql: string): string => {
  if (!sql || !sql.trim()) return sql

  let formatted = sql
    // 标准化空白字符
    .replace(/\s+/g, ' ')
    .trim()

  // 主要关键字前换行
  const majorKeywords = [
    'SELECT', 'FROM', 'WHERE', 'GROUP BY', 'HAVING', 'ORDER BY', 'LIMIT',
    'INSERT INTO', 'UPDATE', 'DELETE FROM', 'CREATE TABLE', 'ALTER TABLE', 'DROP TABLE',
    'WITH', 'UNION', 'UNION ALL', 'INTERSECT', 'EXCEPT'
  ]

  majorKeywords.forEach(keyword => {
    const regex = new RegExp(`\\b${keyword}\\b`, 'gi')
    formatted = formatted.replace(regex, `\n${keyword}`)
  })

  // JOIN关键字处理
  const joinKeywords = ['JOIN', 'INNER JOIN', 'LEFT JOIN', 'RIGHT JOIN', 'FULL JOIN', 'CROSS JOIN']
  joinKeywords.forEach(join => {
    const regex = new RegExp(`\\b${join}\\b`, 'gi')
    formatted = formatted.replace(regex, `\n${join}`)
  })

  // 子查询缩进
  formatted = formatted.replace(/\(\s*SELECT/gi, '(\n  SELECT')
  formatted = formatted.replace(/\)\s*([,;])/gi, '\n)$1')

  // 逗号后换行（在SELECT子句中）
  formatted = formatted.replace(/,(?=\s*\w)/g, ',\n  ')

  // AND/OR 换行
  formatted = formatted.replace(/\s+(AND|OR)\s+/gi, '\n  $1 ')

  // CASE语句格式化
  formatted = formatted.replace(/\bCASE\b/gi, '\nCASE')
  formatted = formatted.replace(/\bWHEN\b/gi, '\n  WHEN')
  formatted = formatted.replace(/\bTHEN\b/gi, ' THEN')
  formatted = formatted.replace(/\bELSE\b/gi, '\n  ELSE')
  formatted = formatted.replace(/\bEND\b/gi, '\nEND')

  // 函数参数格式化
  formatted = formatted.replace(/,(\s*)(?=[^)]*\))/g, ',\n    ')

  // 清理多余的空行
  formatted = formatted.replace(/\n\s*\n/g, '\n')

  // 添加适当的缩进
  const lines = formatted.split('\n')
  let indentLevel = 0
  const indentSize = 2

  const formattedLines = lines.map(line => {
    const trimmedLine = line.trim()
    if (!trimmedLine) return ''

    // 减少缩进的关键字
    if (/^(FROM|WHERE|GROUP BY|HAVING|ORDER BY|LIMIT|UNION|INTERSECT|EXCEPT|\)|END)$/i.test(trimmedLine)) {
      indentLevel = Math.max(0, indentLevel - 1)
    }

    const indentedLine = ' '.repeat(indentLevel * indentSize) + trimmedLine

    // 增加缩进的关键字
    if (/^(SELECT|FROM|WHERE|GROUP BY|HAVING|ORDER BY|JOIN|INNER JOIN|LEFT JOIN|RIGHT JOIN|FULL JOIN|CROSS JOIN|CASE|WHEN|\()$/i.test(trimmedLine)) {
      indentLevel++
    }

    return indentedLine
  })

  // 最终清理
  return formattedLines
    .join('\n')
    .replace(/^\s+/, '') // 移除开头空白
    .replace(/\s+$/, '') // 移除结尾空白
    .replace(/\n{3,}/g, '\n\n') // 限制连续空行
}

/**
 * 获取执行状态的颜色
 */
export const getExecutionStatusColor = (status: string): string => {
  const colorMap: Record<string, string> = {
    running: '#52c41a',
    completed: '#1890ff',
    failed: '#ff4d4f',
    cancelled: '#d9d9d9',
  }
  
  return colorMap[status] || '#d9d9d9'
}

/**
 * 获取执行状态的文本
 */
export const getExecutionStatusText = (status: string): string => {
  const textMap: Record<string, string> = {
    running: '执行中',
    completed: '已完成',
    failed: '执行失败',
    cancelled: '已取消',
  }
  
  return textMap[status] || '未知状态'
}